package com.bdcom.autotest.telnet;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TelnetNotificationHandler;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;

/**
 * telnet 客户端(针对串口服务器的telnet客户端)
 * @author jjl
 *
 */
public class TelnetClientForCOM implements Runnable, TelnetNotificationHandler {
	private static final Log logger = LogFactory.getLog(TelnetClientForCOM.class);
	
	
	private TelnetClient telnetClient = null;
	private String remoteip;
	private int remotePort;
	private StringBuffer responseStr = new StringBuffer();

	public TelnetClientForCOM(String ip) throws Exception{
		this(ip, 23, null);
	}

	public TelnetClientForCOM(String ip, int port) throws Exception{
		this(ip, port, null);
	}

	public TelnetClientForCOM(String ip, String spyFile) throws Exception{
		this(ip, 23, spyFile);
	}

	/**
	 * @param ip
	 * @param port
	 * @param spyFile
	 */
	public TelnetClientForCOM(String ip, int port, String spyFile) throws Exception{
		remoteip = ip;
		remotePort = port;
		initClient(spyFile);
	}

	private void initClient(String spyFile) throws Exception{
		telnetClient = new TelnetClient();
		TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT220", false, false, true, false);// telnet有VT100 VT52  VT220 VTNT ANSI等协议。
		EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
		SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);
		try {
			telnetClient.addOptionHandler(ttopt);
			telnetClient.addOptionHandler(echoopt);
			telnetClient.addOptionHandler(gaopt);
			
			if (null != spyFile && !"".equals(spyFile)) {
				FileOutputStream fout = null;
				try {
					fout = new FileOutputStream("spy.log", true);
					telnetClient.registerSpyStream(fout);
				} catch (IOException e) {
					logger.error("Exception while opening the spy file: " + e.getMessage());
				}
			}
			
		} catch (Exception e) {
			throw new Exception("Init TelnetClient failed!", e);
		}

	}

	/**
	 * 
	 * @param waitTime 等待设备相应时间
	 * @return
	 * @throws Exception
	 */
	public String connect(long waitTime) throws Exception {
		try {
			telnetClient.connect(remoteip, remotePort);

			Thread reader = new Thread(this);
			telnetClient.registerNotifHandler(this);

			reader.start();
			return getResponse(waitTime);
		} catch (ConnectException e) {
			throw new ConnectException("Telnet connection failed!");
		}
	}

	public void disConnect() throws Exception{
		try {
			if (telnetClient != null && telnetClient.isConnected()){
				telnetClient.disconnect();
			}
		} catch (Exception e) {
			throw new Exception("Disconnect telnet client error!", e);
		}
	}


	/**
	 * 发送命令
	 * 
	 * @param command 命令
	 * @param waitTime  获取返回结果时等待时间，在等待的时间内若返回的结果不是想要的结果，可以调用 getResponse(long waitTime)继续获取
	 * @return 执行结果
	 * @throws Exception
	 */
	public String sendCommand(String command, Long waitTime) throws Exception {

		try {
			responseStr.delete(0, responseStr.capacity());
			OutputStream outstr = telnetClient.getOutputStream();
            if(!command.equals("\r\n")){
				outstr.write(command.getBytes("utf-8"));
			}
			outstr.write(13);
			outstr.write(10);
			outstr.flush();
		} catch (Exception e) {
			throw new Exception("Telnet send command [" + command + "] failed! Maybe COM Port has used!", e);
		}

		return getResponse(waitTime);

	}

	@Override
	public void receivedNegotiation(int negotiation_code, int option_code) {
		String command = null;
		if (negotiation_code == TelnetNotificationHandler.RECEIVED_DO) {
			command = "DO";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_DONT) {
			command = "DONT";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_WILL) {
			command = "WILL";
		} else if (negotiation_code == TelnetNotificationHandler.RECEIVED_WONT) {
			command = "WONT";
		}
//		logger.info("Received " + command + " for option code " + option_code);
	}

	/***
	 * Reader thread. Reads lines from the TelnetClient and echoes them .
	 ***/
	// @Override
	public void run() {
		InputStream instr = telnetClient.getInputStream();
		try {
			byte[] buff = new byte[1024];
			int ret_read = 0;
			do {
				ret_read = instr.read(buff);
				if (ret_read > 0) {
					responseStr.append(new String(buff, 0, ret_read, "GBK"));
				}	
			} while (ret_read >= 0);
		} catch (Exception e) {
			logger.error("Exception while reading socket:" + e.getMessage());
		}
	}

	/**
	 * 获取命令返回去
	 * @param waitTime  等待时间
	 * @return
	 */
	public String getResponse(long waitTime) {
		try {
			Thread.sleep(waitTime);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return responseStr.toString();
	}

	
	

	public TelnetClient getTc() {
		return telnetClient;
	}

	public void setTc(TelnetClient tc) {
		this.telnetClient = tc;
	}

	public String getRemoteip() {
		return remoteip;
	}

	public void setRemoteip(String remoteip) {
		this.remoteip = remoteip;
	}

	public int getRemoteport() {
		return remotePort;
	}

	public void setRemoteport(int remoteport) {
		this.remotePort = remoteport;
	}

	public StringBuffer getResponseStr() {
		return responseStr;
	}

	public void setResponseStr(StringBuffer responseStr) {
		this.responseStr = responseStr;
	}

	public static void main(String[] args) throws Exception {

//		WebTelnetClient client = new WebTelnetClient("172.16.21.119");
//		String welcome = client.connect(500);
//		
//		System.out.println(welcome);
//		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//		while(true){
//	         String str = br.readLine();
//	         String responseCommand = client.sendCommand(str, 500L);
//	         System.out.println(responseCommand);
//		}
//		util.disConnect();
		
			TelnetClientForCOM client = new TelnetClientForCOM("192.168.40.139",1);
			
			String connect = client.connect(2000);
			System.out.println(connect);
			String retStr0 = client.sendCommand("\r\n", 200l);
			String retStr1 = client.sendCommand("admin", 200l);
			String retStr2 = client.sendCommand("admin", 200l);
			String retStr3 = client.sendCommand("ena", 200l);
		    String retStr4 = client.sendCommand("show version", 1000l);
		    String retStr5 = client.sendCommand("exit", 200l);
		    String retStr6 = client.sendCommand("exit", 200l);

			//System.out.println(  retStr0 );
			System.out.println(  retStr1 );
			System.out.println(  retStr2 );
			System.out.println(  retStr3 );
			System.out.println(  retStr4 );


//			String retStr4 = client.sendCommand("show run", 2000l);
//			System.out.println(  retStr4 );
			
			client.disConnect();
			

	}

}
